package com.sj.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sj.common.exception.CustomException;
import com.sj.common.lang.ApiResultMsg;
import com.sj.common.lang.ResultInfo;
import com.sj.dto.UserDto;
import com.sj.entity.User;
import com.sj.service.UserService;
import com.sj.utils.MineUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * <p>
 * 用户模块前端控制器
 * </p>
 *
 * @author 小七
 * @since 2021-07-30
 */
@Api(tags = "用户模块")
@RestController
@RequestMapping("/api/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private MineUtils mineUtils;

    @GetMapping("/detail/{id}")
    @ApiOperation(value = "根据用户id查询用户详情")
    public ApiResultMsg<User> getUserDetail(@PathVariable("id") @ApiParam(name = "id", value = "用户id", required = true, defaultValue = "1") Integer id) {
        User userDetail = userService.getById(id);
        if (userDetail == null) {
            return ApiResultMsg.error(ResultInfo.NOT_FONT);
        }
        userDetail.setPassword(null);
        userDetail.setStatus(null);
        return ApiResultMsg.success(ResultInfo.SUCCESS,
                MapUtil.builder()
                        .put("userInfo", userDetail)
                        .build());
    }


    @PostMapping("/update")
    @ApiOperation(value = "根据id修改用户信息")
    public ApiResultMsg<User> updateById(@RequestBody User user) {
        user.setUsername(null);
        user.setPassword(null);
        if (!StrUtil.isBlankOrUndefined(user.getPassword())) {
            return ApiResultMsg.error("不能修改密码");
        }
        if (user.getId() == null) {
            return ApiResultMsg.error("请传递用户id");
        }
        boolean result = userService.updateById(user);
        if (result) {
            return ApiResultMsg.success(ResultInfo.SUCCESS);
        }
        return ApiResultMsg.error(ResultInfo.ERROR);
    }

    @GetMapping("/generate/{birthday}")
    @ApiOperation(value = "根据生日生成生肖和属相")
    public ApiResultMsg<User> generateInfo(@PathVariable("birthday") @ApiParam(name = "birthday", value = "生日") String birthday) {
        try {
            if (StrUtil.isBlankOrUndefined(birthday)) {
                return ApiResultMsg.error("请输入生日");
            }
            DateTime date = DateUtil.parse(birthday);
            String constellations = DateUtil.getZodiac(DateUtil.month(date), DateUtil.dayOfMonth(date));
            String animal = DateUtil.getChineseZodiac(DateUtil.year(date));
            return ApiResultMsg.success(ResultInfo.SUCCESS,
                    MapUtil.builder()
                            .put("constellations", constellations)
                            .put("animal", animal)
                            .build());
        } catch (Exception e) {
            throw new CustomException("日期格式不正确");
        }
    }

    @PostMapping("/updatePass")
    @ApiOperation(value = "修改密码接口")
    public ApiResultMsg<User> updatePassword(@RequestBody @Validated UserDto userDto) {
        if (userDto.getId() == null) {
            return ApiResultMsg.error("id不能为空");
        }
        if (StrUtil.isBlankOrUndefined(userDto.getOldpassword())) {
            return ApiResultMsg.error("原始密码不能为空");
        }
        if (!userDto.getPassword().equals(userDto.getRepassword())) {
            return ApiResultMsg.error("两次密码不一致");
        }
        User checkUser = userService.getById(userDto.getId());
        if (!bCryptPasswordEncoder.matches(userDto.getOldpassword(), checkUser.getPassword())) {
            return ApiResultMsg.error("原始密码错误");
        }
        String encode = bCryptPasswordEncoder.encode(userDto.getPassword());
        User user = new User();
        user.setId(userDto.getId());
        user.setPassword(encode);
        boolean result = userService.updateById(user);
        if (result) {
            return ApiResultMsg.success("修改成功，请重新登录");
        }
        return ApiResultMsg.error(ResultInfo.ERROR);
    }


    @GetMapping("/checkUsername/{username}")
    @ApiOperation(value = "检查用户名是否存在")
    public ApiResultMsg<User> check(@PathVariable("username") String username) {
        Integer count = userService.count(new QueryWrapper<User>().eq("username", username));
        if (count > 0) {
            return ApiResultMsg.error(ResultInfo.ALREADY_EXIST);
        }
        return ApiResultMsg.success("用户名可用");
    }

    @PutMapping("/register")
    @ApiOperation(value = "注册接口")
    public ApiResultMsg<User> register(@RequestBody @Validated UserDto userDto) {
        if (StrUtil.isBlankOrUndefined(userDto.getUsername())) {
            return ApiResultMsg.error("用户名不能为空");
        }
        // 校验验证码
        mineUtils.validate(userDto.getKey(), userDto.getCode());
        if (!userDto.getPassword().equals(userDto.getRepassword())) {
            return ApiResultMsg.error("两次密码不一致");
        }
        User user = new User();
        BeanUtil.copyProperties(userDto, user);
        user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
        boolean result = userService.save(user);
        if (result) {
            return ApiResultMsg.success(ResultInfo.SUCCESS);
        }
        return ApiResultMsg.error(ResultInfo.ERROR);
    }

}

